#include "HollowOperationWidget.h"

#include "Core/MainWindow.h"
#include <QMessageBox>
#include <TopTools_ListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <BRepOffsetAPI_MakeThickSolid.hxx>
#include "FeatureShape/HistoryManager.h"
#include "FeatureShape/FeatureShape.h"
#include <TopExp_Explorer.hxx>

HollowOperationWidget::HollowOperationWidget(MainWindow* inMainWindow, ShapeOperation* inOperation, QWidget* parent)
	: QRSWidgetBase(inMainWindow, inOperation, parent)
	, ui(new Ui::HollowOperationWidgetClass())
{
	ui->setupUi(this);

	connect(m_mainWindow, &MainWindow::OnSelectedSubShapes, this, &HollowOperationWidget::OnSelectedSubShapes);
	connect(ui->modifyButton, &QPushButton::clicked, this, &HollowOperationWidget::OnModify);
	connect(ui->confirmButton, &QPushButton::clicked, this, &HollowOperationWidget::OnConfirm);
	connect(ui->cancelButton, &QPushButton::clicked, this, &HollowOperationWidget::close);

	ui->confirmButton->setEnabled(false);
}

HollowOperationWidget::~HollowOperationWidget()
{
	delete ui;
}

void HollowOperationWidget::closeEvent(QCloseEvent* event)
{
	disconnect(m_mainWindow, &MainWindow::OnSelectedSubShapes, this, &HollowOperationWidget::OnSelectedSubShapes);

	if (!bIsConfirmed)
	{
		if (cacheActor)
		{
			m_mainWindow->RemoveActorFromRenderer(cacheActor);
			cacheActor = nullptr;
		}

		if (m_selectedActor)
		{
			m_selectedActor->SetPipelineVisibility(true);
		}
	}

	m_mainWindow->SubWidgetClose(bIsConfirmed);
}

void HollowOperationWidget::OnSelectedSubShapes(QIVtkSelectionPipeline* actor)
{
	if (!ui->modifyButton->isEnabled())
	{
        return;
	}

	m_selectedActor = actor;
	m_shapelist = m_mainWindow->GetSelectedShapes();
}

void HollowOperationWidget::OnModify()
{
	if (m_selectedActor.IsNull())
	{
		QMessageBox::warning(this, "警告", "无效抽壳对象");
		return;
	}

	if ((IsNearlyZero(ui->thickness->value())))
	{
		QMessageBox::warning(this, "警告", "请输入有效的抽壳厚度");
		return;
	}

	TopTools_ListOfShape facesToRemove;
	facesToRemoveCache.clear();
	for (const auto& it : m_shapelist)
	{
		TopoDS_Face face = TopoDS::Face(it);
		if (face.IsNull())
		{
			QMessageBox::warning(this, "警告", "选择了非面的拓扑形状");
			return;
		}
		else
		{
			facesToRemove.Append(face);
			facesToRemoveCache.push_back(face);
		}
	}

	BRepOffsetAPI_MakeThickSolid hollowMaker;
	hollowMaker.MakeThickSolidByJoin(m_selectedActor->OccShape(), facesToRemove, ui->thickness->value(), Precision::Confusion());
	hollowMaker.Build();
	if (hollowMaker.Shape().IsNull())
	{
		QMessageBox::warning(this, "警告", "抽壳失败");
		return;
	}

	gp_Pnt pos = m_selectedActor->m_position;
	cacheActor = m_mainWindow->createBasicUnitActor(hollowMaker.Shape());
	cacheActor->m_position = pos;
	ui->confirmButton->setEnabled(true);
	ui->modifyButton->setEnabled(false);

	m_selectedActor->SetPipelineVisibility(false);
	_thickness = ui->thickness->value();
}

void HollowOperationWidget::OnConfirm()
{
	bIsConfirmed = true;

	int shapeIndex = GetIndexFromActor(m_mainWindow->GetCachedActors(), m_selectedActor);
	std::vector<int> faceIndex;
	TopExp_Explorer explorer(m_selectedActor->OccShape(), TopAbs_FACE);
	int i = 0;
	while (explorer.More())
	{
		if (std::find(facesToRemoveCache.begin(), facesToRemoveCache.end(), TopoDS::Face(explorer.Current())) != facesToRemoveCache.end())
		{
			faceIndex.push_back(i);
		}
		i++;
		explorer.Next();
	}

	if (cacheActor)
	{
		m_mainWindow->OnActorConfirmCreate(cacheActor);
		cacheActor->m_featureShape.reset(new FeatureShapeMix(cacheActor->OccShape()));
	}

	if (m_selectedActor)
	{
		m_mainWindow->RemoveActorFromRenderer(m_selectedActor);
	}

	HollowOperation* op = new HollowOperation("挖空运算", shapeIndex, _thickness, faceIndex);
	m_mainWindow->GetHistoryManager()->applyOperation(op);

	close();
}
